#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <dlfcn.h>
#include <pthread.h>
#include <linux/fb.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/shm.h>

sem_t *sem;

void cleanup(int sig)
{
    sem_close(sem);
    sem_unlink("data");
    exit(0);
}

int main(int argc, char const *argv[])
{
    signal(SIGINT, cleanup);

    // 1， 创建共享内存IPC
    key_t key = ftok(".", 1);   
    int shmid = shmget(key, 128, IPC_CREAT|0666);

    // 2，将SHM映射到本进程的内存空间
    //    NULL: 让Linux自动为本SHM分配虚拟地址入口
    //    0   : 以读写方式映射
    char *p = shmat(shmid, NULL, 0);
    if(p == (void*)-1)
    {
        perror("shmat失败");
        exit(0);
    }

    // 搞个具名信号量
    sem = sem_open("data", O_CREAT|O_EXCL|O_RDWR, 0666, 0);
    if(sem == SEM_FAILED && errno == EEXIST)
    {
        sem = sem_open("data", O_RDWR);
    }
    else if(sem == SEM_FAILED)
    {
        perror("sem_open() failed");
        exit(0);
    }

    // 3，从SHM读出数据
    while(1)
    {
        if(sem_wait(sem) == -1) // P操作，等待对方资源
            break;
        printf("%s", p);
    }

    return 0;
}
